package com.abo.yaas.view.widgets.forms;

import org.vaadin.dialogs.ConfirmDialog;
import org.vaadin.henrik.superimmediatetextfield.SuperImmediateTextField;

import com.abo.yaas.authentication.SessionHandler;
import com.abo.yaas.domain.User;
import com.abo.yaas.i18n.TranslationUtil;
import com.abo.yaas.view.ViewHandler;
import com.abo.yaas.view.widgets.CommunicationExceptionNotification;
import com.abo.yaas.view.widgets.LocaleSensitiveButton;
import com.abo.yaas.view.widgets.fields.CustomTextField;
import com.abo.yaas.view.widgets.fields.UploadImageField;
import com.abo.yaas.view.widgets.panels.AuctionTablePanel;
import com.abo.yaas.view.widgets.validators.EmailValidator;
import com.abo.yaas.webservice.ResourceProvider;
import com.abo.yaas.webservice.exceptions.CommunicationException;
import com.vaadin.data.Item;
import com.vaadin.data.Validator.EmptyValueException;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.validator.NullValidator;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.PasswordField;

@SuppressWarnings("serial")
public class UserForm extends Form implements Button.ClickListener {
    private static class UserFormFieldFactory extends DefaultFieldFactory {
        public UserFormFieldFactory() {
            super();
        }

        @Override
        public Field createField(Item item, Object propertyId, Component uiContext) {
            Field result = null;
            if ("userPic".equals(propertyId)) {
                result = new UploadImageField(uiContext.getApplication());
                result.addValidator(new NullValidator("Please choose user pic!", false));
            }
            if ("firstName".equals(propertyId) || "lastName".equals(propertyId) || "login".equals(propertyId)) {
                result = new CustomTextField();
                result.addValidator(new NullValidator("The field must not be blank!", false));
            }
            if ("password".equals(propertyId) || "duplicatePassword".equals(propertyId)) {
                result = new PasswordField();
                result.setWidth("100%");
                result.addValidator(new NullValidator("The password should be set!", false));
            }
            if ("email".equals(propertyId)) {
                result = new SuperImmediateTextField();
                result.setWidth("100%");
                result.addValidator(new EmailValidator("Invalid E-Mail"));
                result.addValidator(new NullValidator("Please choose user pic!", false));
            }
            if (result != null) {
                result.setCaption(TranslationUtil.getFieldTranslation(User.class, (String) propertyId));
            }
            return result;
        }
    }

    private final GridLayout layout = new GridLayout(2, 7);

    private Boolean isEdditing = false;

    public UserForm() {
        super();
        layout.setSizeUndefined();
        layout.setSpacing(true);
        layout.setWidth("100%");
        setLayout(layout);
        setImmediate(true);
        setWriteThrough(false);
        setFormFieldFactory(new UserFormFieldFactory());
        setupFooter();
    }

    @Override
    protected void attachField(Object propertyId, Field field) {
        if (propertyId.equals("userPic")) {
            layout.addComponent(field, 0, 0, 0, 4);
            return;
        }
        if (propertyId.equals("firstName")) {
            layout.addComponent(field, 1, 0);
            return;
        }
        if (propertyId.equals("lastName")) {
            layout.addComponent(field, 1, 1);
            return;
        }
        if (propertyId.equals("login")) {
            layout.addComponent(field, 1, 2);
            return;
        }
        if (propertyId.equals("password")) {
            layout.addComponent(field, 1, 3);
            return;
        }
        if (propertyId.equals("duplicatePassword")) {
            layout.addComponent(field, 1, 4);
            return;
        }
        if (propertyId.equals("email")) {
            layout.addComponent(field, 0, 5, 1, 5);
            return;
        }
    }

    @Override
    public void buttonClick(ClickEvent event) {
    }

    public void changePassword() {

    }

    @Override
    @SuppressWarnings("unchecked")
    public void commit() throws SourceException, InvalidValueException {
        try {
            super.commit();
            User user = ((BeanItem<User>) getItemDataSource()).getBean();
            if (user != null) {
                if (!isEdditing) {
                    user = ResourceProvider.get().getUserProxy().register(user);
                } else {
                    user = ResourceProvider.get().getUserProxy().saveEntity(user);
                }
            }
            SessionHandler.setUser(user);
        } catch (final CommunicationException e) {
            getWindow().showNotification(new CommunicationExceptionNotification(e));
        } catch (final EmptyValueException e) {
            getWindow().showNotification(new CommunicationExceptionNotification(e.getMessage()));
        }
    }

    @Override
    public void discard() throws SourceException {
        super.discard();
        ViewHandler.activateView(AuctionTablePanel.class);
    }

    public Boolean getIsEdditing() {
        return isEdditing;
    }

    public void setIsEdditing(Boolean isEdditing) {
        this.isEdditing = isEdditing;
    }

    private void setupFooter() {
        final Button okButton = new LocaleSensitiveButton("OK_BUTTON", this, "submit");
        final Button cancelButton = new LocaleSensitiveButton("CANCEL_BUTTON", this, "discard");
        final HorizontalLayout footer = new HorizontalLayout();
        footer.setSizeUndefined();
        footer.setMargin(true);
        footer.setSpacing(true);
        footer.addComponent(okButton);
        footer.addComponent(cancelButton);
        setFooter(footer);
    }

    // TODO Move text to resources
    public void submit() {
        final String msg = isEdditing ? "Are You sure you want modify account?" : "Are You sure you want to create the account?";
        ConfirmDialog.show(getWindow(), msg, new ConfirmDialog.Listener() {
            @Override
            public void onClose(ConfirmDialog dialog) {
                if (dialog.isConfirmed()) {
                    commit();
                    ViewHandler.activateView(AuctionTablePanel.class);
                }
            }
        });
    }
}
